#include "network_handler.h"        // 引入网络模块头文件
#include "webserver_handler.h"      // 引入网页配网模块
#include "device_info.h"            // 引入设备信息上报模块
#include "esp_wifi.h"               // 用于调用 esp_wifi_restore()
#include <AsyncUDP.h>               // UDP通信支持
#include <Preferences.h>            // NVS存储支持
#include <Arduino.h>

Preferences prefs;                  // 全局存储对象
AsyncUDP udp;                       // UDP对象

#define WIFI_ERASE_PIN 9            // 长按清除WiFi按钮引脚
const char* ap_ssid = "chiyu_setup"; // AP模式热点名
bool controlled = false;            // 控制标志（UDP接管）
unsigned long lastBroadcastTime = 0; // 上次广播时间
const unsigned long broadcastInterval = 3000; // UDP广播间隔3秒

static bool wifiReady = false;      // WiFi 栈是否已初始化
static bool webStarted = false;     // WebServer 是否已启动

// ================================================================
// 延迟检测：确保 WiFi 栈就绪再进行后续操作（避免 xQueueSemaphoreTake 崩溃）
// ================================================================
bool waitForWiFiReady(uint32_t timeout) {
  unsigned long start = millis();
  while (WiFi.getMode() == WIFI_OFF && millis() - start < timeout) {  
    delay(100);
  }
  return (WiFi.getMode() != WIFI_OFF);
}


// ================================================================
// 检查开机是否要清除WiFi配置
// ================================================================
void doFullWifiEraseOnBoot() {
  Preferences f;
  f.begin("wipe", true);
  bool need = f.getBool("all", false);
  f.end();
  if (!need) return;

  Serial.println("[BOOT] 执行：清除系统层与应用层 WiFi 配置…");
  WiFi.mode(WIFI_STA);
  esp_wifi_restore();
  delay(100);

  Preferences p;
  p.begin("wifi", false);
  p.clear();
  p.end();

  f.begin("wipe", false);
  f.clear();
  f.end();

  Serial.println("[BOOT] WiFi信息已清空，设备即将重启");
  delay(300);
  ESP.restart();
}

// ================================================================
// 检测按钮长按清除WiFi
// ================================================================
void pollWifiEraseButtonFull() {
  static bool inited = false, prevLow = false;
  static unsigned long downAt = 0;

  if (!inited) {
    pinMode(WIFI_ERASE_PIN, INPUT_PULLUP);
    inited = true;
  }

  bool low = (digitalRead(WIFI_ERASE_PIN) == LOW);
  unsigned long now = millis();

  if (low && !prevLow) downAt = now;
  if (low && (now - downAt >= 3000)) {
    Serial.println("[BTN] 检测到长按3秒，设置清除WiFi标志");
    Preferences f;
    f.begin("wipe", false);
    f.putBool("all", true);
    f.end();
    delay(200);
    ESP.restart();
  }
  prevLow = low;
}

// ================================================================
// 初始化网络连接
// ================================================================
void initNetwork() {
  Serial.println("[NET] 启动网络模块");
  doFullWifiEraseOnBoot();  // 检查是否需要清除WiFi配置

  prefs.begin("wifi", true);
  String ssid = prefs.getString("ssid", "");
  String pwd = prefs.getString("password", "");
  prefs.end();

  // ------------------- 若存在已保存WiFi配置，尝试连接 -------------------
  if (ssid != "" && pwd != "") {
    Serial.println("[NET] 尝试连接 WiFi: " + ssid);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid.c_str(), pwd.c_str());

    unsigned long start = millis();
    while (WiFi.status() != WL_CONNECTED && millis() - start < 8000) {
      delay(500);
      Serial.print(".");
    }
    Serial.println();

    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("[NET] 连接成功, IP: " + WiFi.localIP().toString());
      wifiReady = true;

      // 启动UDP监听（端口4210）
      udp.listen(4210);
      udp.onPacket([](AsyncUDPPacket packet) {
        if (packet.length() > 0) {
          char cmd = packet.data()[0];
          if (cmd == '8') {
            prefs.begin("wifi", false);
            prefs.clear();
            prefs.end();
            ESP.restart();
          }
        }
      });

      // 确保 WiFi 栈完全启动后再初始化 WebServer
      if (waitForWiFiReady()) {
        Serial.println("[NET] WiFi 栈就绪，启动 WebServer...");
        initWebServer();
        webStarted = true;
      } else {
        Serial.println("[NET] WiFi 栈超时未就绪，暂不启动 WebServer。");
      }

      lastBroadcastTime = millis();
      return;
    } else {
      Serial.println("[NET] WiFi连接失败，进入AP模式");
    }
  }

  // ------------------- 启动AP模式 -------------------
  Serial.println("[NET] 启动配网热点: " + String(ap_ssid));
  WiFi.disconnect(true);
  delay(200);
  WiFi.mode(WIFI_AP);
  delay(100);
  WiFi.softAP(ap_ssid);
  delay(500);

  IPAddress apIP = WiFi.softAPIP();
  Serial.println("[AP] 热点名: " + String(ap_ssid));
  Serial.println("[AP] IP地址: " + apIP.toString());

  if (waitForWiFiReady()) {
    Serial.println("[NET] AP 模式 WiFi 栈就绪，启动 WebServer...");
    initWebServer();
    webStarted = true;
  } else {
    Serial.println("[NET] WiFi 栈启动超时，未能启动 WebServer。");
  }
}

// ================================================================
// 主循环中调用的网络更新
// ================================================================
void handleNetworkLoop() {
  pollWifiEraseButtonFull();  // 检测是否长按清除WiFi

  // ✅ WiFi正常连接时发送UDP广播
  if (!controlled && WiFi.status() == WL_CONNECTED) {
    unsigned long now = millis();
    if (now - lastBroadcastTime >= broadcastInterval) {
      String msg = "connected@" + WiFi.localIP().toString();
      udp.writeTo((const uint8_t*)msg.c_str(), msg.length(),
                  IPAddress(255, 255, 255, 255), 4210);
      Serial.println("[UDP] 广播: " + msg);
      lastBroadcastTime = now;
    }
  }

  // ✅ 若 WiFi 栈晚初始化，也可以在这里补启动 WebServer
  if (wifiReady && !webStarted && WiFi.getMode() != WIFI_OFF) {
    Serial.println("[NET] 延迟检测到 WiFi 栈已初始化，启动 WebServer...");
    initWebServer();
    webStarted = true;
  }
}
